package com.ny.zmb.openapi.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ny.zmb.glxt.entity.PmStore;
import com.ny.zmb.glxt.entity.PmStoreExt;
import com.ny.zmb.glxt.service.IPmStoreService;
import com.ny.zmb.glxt.service.impl.PmStoreServiceImpl;
import com.ny.zmb.openapi.controller.entity.Result;
import com.ny.zmb.openapi.entity.PmRegister;
import com.ny.zmb.openapi.entity.PmRegisterExamine;
import com.ny.zmb.openapi.mapper.PmRegisterMapper;
import com.ny.zmb.openapi.service.PmContractSignService;
import com.ny.zmb.openapi.service.PmRegisterExamineService;
import com.ny.zmb.openapi.service.PmRegisterService;
import com.ny.zmb.openapi.util.DateUtil;
import com.ny.zmb.openapi.util.OSSUtil;
import com.ny.zmb.openapi.ysutil.YsHttpUtil;
import com.ny.zmb.openapi.ysutil.common.ServiceEnum;
import com.ny.zmb.openapi.ysutil.common.SubCodeEnum;
import com.ny.zmb.openapi.ysutil.from.BizReqJsonCollege.*;
import com.ny.zmb.openapi.ysutil.utils.RequestNoUntil;
import com.ny.zmb.openapi.ysutil.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

import java.io.IOException;
import java.io.InputStream;

import static com.ny.zmb.openapi.constant.PHPConstant.JAVA_BASE_URL;
import static com.ny.zmb.openapi.ysutil.utils.Base64Utils.encodeImageToBase64;

/**
 * 进件
 *
 * @author ChenZhiZheng
 * @date 20241108
 */
@Service
public class PmRegisterServiceImpl extends ServiceImpl<PmRegisterMapper, PmRegister> implements PmRegisterService {

    @Resource
    private YsHttpUtil ysHttpUtil;
    @Resource
    private OSSUtil ossUtil;
    @Resource
    private PmRegisterMapper pmRegisterMapper;
    @Resource
    private PmRegisterExamineService pmRegisterExamineService;
    @Resource
    private IPmStoreService pmStoreService;
    @Resource
    private PmContractSignService pmContractSignService;

    QueryWrapper<PmRegister> pmRegisterQueryWrapper = new QueryWrapper<>();


    /**
     * 进件资料上传 更新进件资料和审核表
     *
     * @param jsonObject 对象
     * @return 返回体
     */
    @Transactional
    @Override
    public Result infoUpdate(JSONObject jsonObject, Integer userId) {
        BizReqJsonRegister registerObj;
        PmRegister pmRegister;
        PmRegisterExamine pmRegisterExamine;
        JSONObject result = new JSONObject();
        // 转换对象
        try {
            registerObj = jsonObject.toJavaObject(BizReqJsonRegister.class);
        } catch (Exception e) {
            throw new RuntimeException("对象转换错误");
        }
        String outMerchantNo = registerObj.getOutMerchantNo();
        // 信息确认
        pmRegister = getInfoByUserId(userId);
        // 查询结果不为空 且商户号不同
        if (pmRegister != null && !outMerchantNo.equals(pmRegister.getOutMerchantNo())) {
            throw new RuntimeException("账号信息错误,您已经申请了外部商户号,商户号为:" + pmRegister.getOutMerchantNo());
        }
        // 获取进件资料
        pmRegister = getInfoByOutMerchantNo(outMerchantNo);
        // 获取审核资料
        pmRegisterExamine = pmRegisterExamineService.getByOutMerchantNo(outMerchantNo);

        // 更新资料 || 资料状态检查
        if (pmRegisterExamine == null) {
            pmRegisterExamine = new PmRegisterExamine(userId, outMerchantNo);
            // 资料审核状态为 未提交 更新时间
            pmRegisterExamine = pmRegisterExamine.updateYS(0, null);
            pmRegisterExamine = pmRegisterExamine.updateZMB(0, null);
        } else {
            // 校验信息
            if (!userId.equals(pmRegisterExamine.getUserId())) {
                throw new RuntimeException("账号信息错误,该商户号已被其他账号使用");
            }
            // 需要 更新资料状态 为未提交
            if (pmRegisterExamine.getStatus() != 0) {
                result.put("msg", pmRegisterExamine.zmbStatusJudge());
                result.put("register", pmRegister);
                result.put("registerExamine", pmRegisterExamine);
                return Result.fail(result);
            }
            if (pmRegisterExamine.getYsStatus() != 0) {
                result.put("msg", pmRegisterExamine.ysStatusJudge());
                result.put("register", pmRegister);
                result.put("registerExamine", pmRegisterExamine);
                return Result.fail(result);
            }
        }
        // 更新基础资料
        if (pmRegister == null) {
            pmRegister = new PmRegister(outMerchantNo, userId);
        } else {
            if (!userId.equals(pmRegister.getUserId())) {
                throw new RuntimeException("账号信息错误,该商户号已被其他账号使用");
            }
        }
        pmRegister.update(registerObj);
        // 更新
        boolean pmRegisterFlag = saveOrUpdate(pmRegister);
        boolean pmRegisterExamineFlag = pmRegisterExamineService.saveOrUpdate(pmRegisterExamine);
        if (pmRegisterFlag && pmRegisterExamineFlag) {
            result.put("msg", "更新成功");
        } else {
            throw new RuntimeException("相关表更新失败");
        }
        result.put("register", pmRegister);
        result.put("registerExamine", pmRegisterExamine);
        return Result.ok(result);
    }

    /**
     * 提交审核
     *
     * @param jsonObject
     * @param userId
     * @return
     */
    @Override
    public Result commitInfoToZMB(JSONObject jsonObject, Integer userId) {

        PmRegisterExamine pmRegisterExamine = pmRegisterExamineService.getByOutMerchantNo(jsonObject.getString("outMerchantNo"));
        if (pmRegisterExamine == null) {
            return Result.fail("未找到对应审核记录");
        } else {
            if (!userId.equals(pmRegisterExamine.getUserId())) {
                throw new RuntimeException("该记录非当前用户创建");
            }
            // 提交修改
            pmRegisterExamine.updateZMB(3, null);
            boolean b = pmRegisterExamineService.updateById(pmRegisterExamine);
            return b ? Result.ok("提交成功", pmRegisterExamine) : Result.fail("提交失败");
        }
    }

    /**
     * 状态变更
     *
     * @param jsonObject
     * @return
     */
    @Override
    public Result changeStatus(JSONObject jsonObject) {
        try {
            return pmRegisterExamineService.changeStatus(jsonObject);
        } catch (Exception var) {
            return Result.fail(var.getMessage());
        }
    }

    /**
     * 提交申请到银盛审核
     *
     * @param jsonObject
     * @param srcMerchantNo
     * @return
     */
    @Override
    public Result commitToYs(JSONObject jsonObject, String srcMerchantNo) {
        JSONObject result = new JSONObject();
        String outMerchantNo = jsonObject.getString("outMerchantNo");
        PmRegisterExamine pmRegisterExamine = pmRegisterExamineService.getByOutMerchantNo(outMerchantNo);
        PmStore pmStore = pmStoreService.getInfoByOutMerchantNo(outMerchantNo);
        if (pmStore == null){
            return Result.fail("没有找到" + outMerchantNo + "该商户号的店铺信息");
        }else{
            // 判断ZMB审核状态
            if (pmStore.getStatus() != 1) {
                return Result.fail("外部商户号: " + outMerchantNo + " 店铺状态为: " + pmStore.judgeStatus());
            }
        }
        if (pmRegisterExamine == null) {
            return Result.fail("没有找到" + outMerchantNo + "该商户号的审核记录");
        } else {
            // 判断ZMB审核状态
            if (pmRegisterExamine.getStatus() != 1) {
                return Result.fail("外部商户号: " + outMerchantNo + " " + pmRegisterExamine.zmbStatusJudge());
            }
        }
        PmRegister pmRegister = getInfoByOutMerchantNo(outMerchantNo);
        pmRegister.setNotifyAddress(JAVA_BASE_URL + "/notify/registerNotify");
        if (StringUtils.isEmpty(pmRegister.getMerchantType())) {
            throw new RuntimeException("店铺类型异常");
        } else if ("04".equals(pmRegister.getMerchantType())) {
            result.put("tip", "此商户类型为" + "此商户类型为" + "会员商户,无需执行进件流程");
            pmRegisterExamineService.saveOrUpdate(pmRegisterExamine.updateYS(6, "此商户类型为" + "会员商户,无需执行进件流程"));
        } else {
            result = doActive(ServiceEnum.REGISTER, srcMerchantNo, pmRegister);
            // 提交资料到银盛之后修改状态记录
            pmRegisterExamineService.saveOrUpdate(pmRegisterExamine.updateYS(5, null));
        }
        result.put("registerInfo", pmRegister);
        return Result.ok(result);
    }

    /**
     * 该接口可用于查询商户进件的结果、商户信息、商户状态等
     *
     * @param obj           参数
     * @param srcMerchantNo 商户号
     * @return 结果
     */
    @Override
    public Object queryMerchant(JSONObject obj, String srcMerchantNo) {
        String merchantNo = obj.getString("merchantNo");
        String outMerchantNo = obj.getString("outMerchantNo");
        Integer userId = obj.getInteger("userId");
        JSONObject returnObj = doActive(ServiceEnum.QUERY_MERCHANT, srcMerchantNo, obj);
        String subCode = returnObj.getString("subCode");
        PmRegisterExamine pmRegisterExamine = pmRegisterExamineService.getByOutMerchantNo(outMerchantNo);
        pmRegisterExamine = pmRegisterExamine == null ? new PmRegisterExamine(userId, outMerchantNo) : pmRegisterExamine;
        if (SubCodeEnum.COM000.getCode().equals(subCode)) {
            pmRegisterExamine.updateYS(1, returnObj.toString());
        } else if (SubCodeEnum.COM001.getCode().equals(subCode)) {
            pmRegisterExamine.updateYS(-1, returnObj.toString());
        } else if (SubCodeEnum.COM002.getCode().equals(subCode)) {
            pmRegisterExamine.updateYS(-1, returnObj.toString());
        } else if (SubCodeEnum.COM003.getCode().equals(subCode)) {
            pmRegisterExamine.updateYS(-1, returnObj.toString());
        } else if (SubCodeEnum.MER001.getCode().equals(subCode)) {
            pmRegisterExamine.updateYS(5, returnObj.toString());
        } else {
            pmRegisterExamine.updateYS(999, returnObj.toString());
        }
        pmRegisterExamineService.saveOrUpdate(pmRegisterExamine);
        return Result.ok(returnObj);
    }

    /**
     * 通过 outMerchantNo 获取进件信息
     *
     * @param outMerchantNo
     * @return
     */
    @Override
    public PmRegister getInfoByOutMerchantNo(String outMerchantNo) {
        QueryWrapper<PmRegister> pmRegisterQueryWrapper = new QueryWrapper<>();
        pmRegisterQueryWrapper.eq("out_merchant_no", outMerchantNo);
        return pmRegisterMapper.selectOne(pmRegisterQueryWrapper);
    }

    /**
     * 营业执照	            ✅	❌	营业执照上文字需清晰、无遮挡
     * 结算银行卡正面	        ✅	✅	有银行卡号信息一面面
     * 法人身份证正面	        ✅	✅	身份证有照片的一面（人像面）
     * 法人身份证反面	        ✅	✅	身份证有国徽的一面（国徽面）
     * 法人手持身份证正面照片	✅	✅	手持身份证照片上文字需清晰、无遮挡
     * 商户店铺门头照	        ✅	✅	线上场景提供：网页或APP首页截图
     * 商户店铺内景照	        ✅	✅	线上场景提供：网页或APP产品展示页面截图
     * 商户店铺收银台照	    ✅	✅	线上场景提供：网页或APP付款页面截图
     */
    @Override
    public boolean registerForFileUpdate(Integer userId, UploadDocumentReqCommandPlus obj, String ysPath) {
        String outMerchantNo = obj.getOutMerchantNo();
        QueryWrapper<PmRegister> pmRegisterQueryWrapper = new QueryWrapper<>();
        pmRegisterQueryWrapper.eq("user_id", userId);
        // 对象转换
        // todo 待加二次校验
        PmRegister pmRegister = pmRegisterMapper.selectOne(pmRegisterQueryWrapper);

        pmRegister = pmRegister == null ? new PmRegister(obj.getOutMerchantNo(), userId) : pmRegister;
        // 上传
        switch (obj.getImgType()) {
            case "LOGO":
                break;
            case "Banner":
                break;
            case "电子协议签名":
                break;
            case "对赌协议签名":
                break;
            case "担保协议签名":
                break;
            case "营业执照":
                pmRegister.setBusinessPic(ysPath);
                break;
            case "结算账户卡正面":
                pmRegister.setAccountCardPicFront(ysPath);
                break;
            case "法人证件正面":
                pmRegister.setLawyerIdPicFront(ysPath);
                break;
            case "法人证件反面":
                pmRegister.setLawyerIdPicBack(ysPath);
                break;
            case "法人手持证件正面":
                pmRegister.setLawyerIdHandFront(ysPath);
                break;
            case "门头照图片":
                pmRegister.setDoorFrontPic(ysPath);
                break;
            case "收银台照图片":
                pmRegister.setCashierPic(ysPath);
                break;
            case "场景照图片":
                pmRegister.setScenePic(ysPath);
                break;
            default:
                throw new RuntimeException("没有找到 " + obj.getImgType() + " 方法");
        }
        return pmRegisterMapper.insertOrUpdate(pmRegister);
    }


    /**
     * 进件成功,调用签约
     *
     * @param merchantInfo
     */
    @Override
    public void registerSuccess(JSONObject merchantInfo) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.putIfAbsent("requestNo", RequestNoUntil.generateNumericTaskNumber());
        jsonObject.putIfAbsent("merchantNo", merchantInfo.getString("merchantNo"));
        jsonObject.putIfAbsent("returnUrl", JAVA_BASE_URL + "/mobile/pages/store/store_gl");
        jsonObject.putIfAbsent("isSendMsg", "Y");
        // 回调
        jsonObject.putIfAbsent("notifyUrl", JAVA_BASE_URL + "/notify/contractSignNotify");
        // 调用签约
        pmContractSignService.contractSign(jsonObject, null);
    }

    /**
     * 上传对象到OSS服务
     *
     * @param file
     * @param name
     * @return
     */
    @Override
    public String fileUploadForOss(MultipartFile file, String name) {
        try {
            InputStream inputStream = file.getInputStream();
            return ossUtil.uploadFileToOSSRandom(name, inputStream, "ys/" + DateUtil.getCurrentDate("yyyyMMdd"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String ossUpload(MultipartFile file, String name, String path) {
        try {
            InputStream inputStream = file.getInputStream();
            return ossUtil.uploadFileToOSSRandom(name, inputStream, path + "/" + DateUtil.getCurrentDate("yyyyMMdd"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 上传对象到银盛
     */
    @Override
    public String filePathUploadForYs(MultipartFile file, String path, UploadDocumentReqCommandPlus obj) {
        if (obj == null) {
            obj = new UploadDocumentReqCommandPlus();
        }
        obj.setRequestNo(RequestNoUntil.generateNumericTaskNumber());
        String fileName = file.getOriginalFilename();
        obj.setFileName(fileName);
        String[] split = fileName.split("\\.");
        obj.setFileType(split[split.length - 1]);
        obj.setFileUrl(path);
        JSONObject result = doActive(ServiceEnum.PIC_UPLOAD, null, obj);
        if (!"COM000".equals(result.getString("subCode"))) return null;
        return result.getString("fileCode");
    }

    @Override
    public Boolean updateMerchantNoByOutMerchantNo(String outMerchantNo, String merchantNo) {
        PmRegister pmRegister = getInfoByOutMerchantNo(outMerchantNo);
        if (pmRegister != null) {
            pmRegister.setMerchantNo(merchantNo);
            return updateById(pmRegister);
        } else {
            return false;
        }
    }

    @Override
    public PmRegister getInfoByUserId(Integer userId) {
        QueryWrapper<PmRegister> pmRegisterQueryWrapper = new QueryWrapper<>();
        pmRegisterQueryWrapper.eq("user_id", userId);
        return pmRegisterMapper.selectOne(pmRegisterQueryWrapper);
    }


    /**
     * 发送请求
     *
     * @param anyEnum
     * @param srcMerchantNo
     * @param obj
     * @return
     */
    private JSONObject doActive(ServiceEnum anyEnum, String srcMerchantNo, Object obj) {
        try {
            JSONObject result = ysHttpUtil.sendBase(anyEnum, "prd", null, null, null, srcMerchantNo, obj);
            return result;
        } catch (Exception var) {
            throw new RuntimeException(var.getMessage());
        }
    }
}


